const originToString = Object.prototype.toString;

type AnyFunction = (..._args: never) => unknown;

export function isFunction(obj: unknown): obj is AnyFunction {
  return typeof obj === "function";
}

export function isBoolean(obj: unknown): obj is boolean {
  return typeof obj === "boolean";
}

export function isString(obj: unknown): obj is string {
  return typeof obj === "string";
}

export function isUndefined(obj: unknown): obj is undefined {
  return obj === "undefined";
}

export function isBigInt(obj: unknown): obj is bigint {
  return typeof obj === "bigint";
}
export function isNumber(obj: unknown): obj is number {
  return typeof obj === "number";
}

export function isSymbol(obj: unknown): obj is symbol {
  return typeof obj === "symbol";
}

//两种都行
// export function isArray<T>(obj: unknown): obj is T[] {
export function isArray(obj: unknown): obj is unknown[] {
  return Array.isArray(obj);
}

export function isObject(obj: unknown): obj is object {
  if (typeof obj !== "object" || obj === null) return false;
  const proto = Object.getPrototypeOf(obj);
  return proto === null || proto === Object.prototype;
}

export function isDate(obj: unknown): obj is Date {
  return originToString.call(obj) === "[object Date]";
}

export function isRegExp(obj: unknown): obj is RegExp {
  return originToString.call(obj) === "[object RegExp]";
}

export function isNull(obj: unknown): obj is null {
  return obj === null;
}

// 判断值是不是可以转换成一个有效数字
export function isNumberical(obj: unknown): obj is number | string | bigint {
  if (typeof obj === "bigint") return true;
  if (typeof obj === "number") return Number.isFinite(obj);
  if (typeof obj === "string") {
    const trimmed = obj.trim();
    if (trimmed === "") return false;
    const numRegex = /^[-+]?(\d+(\.\d*)?|\.\d+)$/;
    return numRegex.test(trimmed) && Number.isFinite(Number(trimmed));
  }
  return false;
}
